/**
 * Project Name:nplus1
 * File Name:RestApiInterceptor.java
 * Package Name:com.gamma.nplus1.modules.sys.interceptor
 * Date:2017年5月18日下午5:38:57
 * Copyright (c) 2017, nplus1 Co., Ltd. All Rights Reserved.
 *
*/

package com.gamma.nplus1.modules.sys.interceptor;

import java.text.SimpleDateFormat;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.NamedThreadLocal;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.gamma.nplus1.common.exception.InvalidSignedException;
import com.gamma.nplus1.common.mapper.JsonMapper;
import com.gamma.nplus1.common.utils.DateUtils;
import com.gamma.nplus1.common.utils.StringUtils;
import com.gamma.nplus1.common.utils.sign.RestapiSignProcessor;
import com.gamma.nplus1.common.utils.sign.StringMap;
import com.gamma.nplus1.modules.sys.utils.LogUtils;

/**
 * ClassName:RestApiInterceptor <br/>
 * Function: rest api 拦截器. <br/>
 * Date:     2017年5月18日 下午5:38:57 <br/>
 * @author   jeno
 * @version  
 * @since    JDK 1.7
 */
public class RestApiInterceptor implements HandlerInterceptor {

	private static final ThreadLocal<Long> startTimeThreadRestapi =
			new NamedThreadLocal<Long>("ThreadRestapi StartTime");
	
	/**
	 * 日志对象
	 */
	protected Logger logger = LoggerFactory.getLogger(getClass());
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		if (logger.isDebugEnabled()){
			long beginTime = System.currentTimeMillis();//1、开始时间  
			startTimeThreadRestapi.set(beginTime);		//线程绑定变量（该数据只有当前请求的线程可见）  
	        logger.debug("开始计时: {}  URI: {}", new SimpleDateFormat("hh:mm:ss.SSS")
	        	.format(beginTime), request.getRequestURI());
		}
		
		//sign string validator
		String appid = request.getParameter(RestapiSignProcessor.ACCESS_APP_ID);
		String signature = request.getParameter(RestapiSignProcessor.ACCESS_SIGNATURE);
		String randStr = request.getParameter(RestapiSignProcessor.ACCESS_RAND_STR);
		String timestrap = request.getParameter(RestapiSignProcessor.ACCESS_TIMESTRAP);
		
		// 验签基本参数
//		if (StringUtils.isBlank(appid)) {
//			throw new InvalidSignedException("param appid not found");
//		}
//		
//		if (StringUtils.isBlank(signature)) {
//			throw new InvalidSignedException("param signature not found");
//		}
//		
//		if (StringUtils.isBlank(randStr)) {
//			throw new InvalidSignedException("param randStr not found");
//		}
//		
//		if (StringUtils.isBlank(timestrap)) {
//			throw new InvalidSignedException("param timestrap not found");
//		}
//		
//		//TODO find secretkey by appid from cache
//		String secretkey = "1293098dkdfh39";
//		
//		//init sign processor
//		RestapiSignProcessor signProcessor = new RestapiSignProcessor(appid,secretkey);
//		
//		//sign
//		Map params = request.getParameterMap();
//		String signedStr = signProcessor.sign(new StringMap(params));
//		
//		if (!StringUtils.equals(signature, signedStr)) {
//			logger.error("sign params {0},signed result:{1}", JsonMapper.toJsonString(params),signedStr);
//			throw new InvalidSignedException("signature fail");
//		}
		
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		
		// 保存日志
		LogUtils.saveLog(request, handler, ex, null);
		
		// 打印JVM信息。
		if (logger.isDebugEnabled()){
			long beginTime = startTimeThreadRestapi.get();//得到线程绑定的局部变量（开始时间）  
			long endTime = System.currentTimeMillis(); 	//2、结束时间  
	        logger.debug("计时结束：{}  耗时：{}  URI: {}  最大内存: {}m  已分配内存: {}m  已分配内存中的剩余空间: {}m  最大可用内存: {}m",
	        		new SimpleDateFormat("hh:mm:ss.SSS").format(endTime), DateUtils.formatDateTime(endTime - beginTime),
					request.getRequestURI(), Runtime.getRuntime().maxMemory()/1024/1024, Runtime.getRuntime().totalMemory()/1024/1024, Runtime.getRuntime().freeMemory()/1024/1024, 
					(Runtime.getRuntime().maxMemory()-Runtime.getRuntime().totalMemory()+Runtime.getRuntime().freeMemory())/1024/1024); 
		}
	}

}

